package gs.eisenhower.swallet.dao;

import gs.eisenhower.swallet.annotation.mapping.Table;
import gs.eisenhower.swallet.db.WalletSqlHelper;
import gs.eisenhower.swallet.model.Entity;
import gs.eisenhower.swallet.utils.methods.WalletUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;

public abstract class GenericDaoImpl implements GenericDao {
    
	private static final WalletSqlHelper DB_HELPER = WalletSqlHelper.getInstance();
//	protected static SQLiteDatabase sqLiteDatabase;
	
	public GenericDaoImpl() {
	}
	
    @Override
    public <T extends Entity> void create(T entity) {
        ContentValues contentValues = new ContentValues();
        final String tableName = entity.getClass().getAnnotation(Table.class).name();
        final Field[] superClassFields  = entity.getClass().getSuperclass().getDeclaredFields();
        final Field[] rootClassFields   = entity.getClass().getSuperclass().getSuperclass().getDeclaredFields();
        final Field[] entityClassFields = entity.getClass().getDeclaredFields();
        
        List<Field> fields = new ArrayList<Field>(Arrays.asList(entityClassFields));
        if (superClassFields.length > 0) {
        	fields.addAll(Arrays.asList(superClassFields));	
        }
        if (rootClassFields.length > 0) {
        	fields.addAll(Arrays.asList(rootClassFields));	
        }
                
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.getName().equals(DB_HELPER.ID_COLUMN)) {
					continue;
				}
				putIntoContentValue(field.getName(), field.get(entity),
						contentValues);
			}
		} catch (IllegalArgumentException exception) {
			exception.printStackTrace();
		} catch (IllegalAccessException exception) {
			exception.printStackTrace();
		}   
        open().insert(tableName, null, contentValues);
        close();
    }
    
    private final void putIntoContentValue(final String fieldName, final Object fieldValue, final ContentValues contentValues) {
        if (!WalletUtils.isNullOrEmpty(fieldName) && fieldValue != null) {
            if (fieldValue instanceof Integer) {
                contentValues.put(fieldName, (Integer) fieldValue);
            } else if (fieldValue instanceof Long) {
                contentValues.put(fieldName, (Long) fieldValue);
            } else if (fieldValue instanceof Double) {
                contentValues.put(fieldName, (Double) fieldValue);
            } else if (fieldValue instanceof Short) {
                contentValues.put(fieldName, (Short) fieldValue);
            } else if (fieldValue instanceof String) {
                contentValues.put(fieldName, (String) fieldValue);
            } else if (fieldValue instanceof Boolean) {
                contentValues.put(fieldName, (Boolean) fieldValue);
            } else if (fieldValue instanceof Float) {
                contentValues.put(fieldName, (Float) fieldValue);
            } else if (fieldValue instanceof Byte) {
                contentValues.put(fieldName, (Byte) fieldValue);
            }
        }   
    }
    
    /**
     * 
     */
    public final SQLiteDatabase open() {
        return DB_HELPER.getWritableDatabase();
    }
    
    /**
     * 
     */
    public final void close() {
        DB_HELPER.close();
    }
    
}
